package com.mq.rabbitmq.point.consumewait;

import org.aopalliance.aop.Advice;
import org.springframework.amqp.rabbit.config.SimpleRabbitListenerContainerFactory;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.amqp.SimpleRabbitListenerContainerFactoryConfigurer;
import org.springframework.context.annotation.Bean;
import org.springframework.retry.interceptor.RetryOperationsInterceptor;

import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * Created by xi on 2017/8/17.
 */
public class MultiConsumerListener {

    @Autowired
    private RabbitTemplate rabbitTemplate;

    /**
     * 单个消费的时候，如果中间的报错，
     * @param configurer
     * @param connectionFactory
     * @return
     */
    @Bean("onePrefetch")
    public SimpleRabbitListenerContainerFactory onePrefetch(
            SimpleRabbitListenerContainerFactoryConfigurer configurer,
            ConnectionFactory connectionFactory,RetryOperationsInterceptor interceptor) {
        SimpleRabbitListenerContainerFactory factory = new SimpleRabbitListenerContainerFactory();
        factory.setPrefetchCount(1);
        factory.setConcurrentConsumers(1);//消费者数量，默认10
        //factory.setDefaultRequeueRejected(false);
       // factory.setAdviceChain(new Advice[]{retryAdvice()});
        factory.setAdviceChain(new Advice[]{interceptor});
        configurer.configure(factory, connectionFactory);
        return factory;
    }


    @Bean("multiPrefetch")
    public SimpleRabbitListenerContainerFactory multiPrefetch(
            SimpleRabbitListenerContainerFactoryConfigurer configurer,
            ConnectionFactory connectionFactory) {
        SimpleRabbitListenerContainerFactory factory = new SimpleRabbitListenerContainerFactory();
        factory.setPrefetchCount(3);
        factory.setConcurrentConsumers(1);//消费者数量，默认10
        configurer.configure(factory, connectionFactory);
        return factory;
    }

    public static final String YYYY_MM_DD_HH_MM_SS = "yyyy-MM-dd HH:mm:ss";
    public static String formateDatetimeStringForDate(Date date){
        SimpleDateFormat sdf = new SimpleDateFormat(YYYY_MM_DD_HH_MM_SS);
        String  s2 = sdf.format(date);
        return s2;
    }

    /**
     * 测试发现多个消费者，其他消费者异常的消息，不会堵住其他消息的确认
     * 如果只有一个消费者，然后一次拉取3个，3个中间有个错误了，不会影响其他2个的确认；
     * 不会堵住后面的确认的，这个是在有重试次数用玩的情况。
     * 如果只有一个消费着，如果第1个挂了，后面的消息都会堵塞住
     * @param data
     */
       // @RabbitListener(queues = AmqpConfig.ROUTINGKEY,containerFactory = "onePrefetch")    //监听器监听指定的Queue
                 public void processC(MultiData data) {
            System.out.println("start<<<<<<<<<<<<<<<<<doWithRetry==="+  formateDatetimeStringForDate(new Date()));
            try{
                String s = null; s.toCharArray();
            }catch (Exception e){
//                System.out.println("<<<<<消息1重试第：" + data.getRetry() + ",次");
//                System.out.println("<<<<<消息1内容："+data.getStr());
//                data.setRetry(data.getRetry()+1);
//                data.setStr(data.getStr()+ "随机数："+new Random().nextInt(1000));
//                try {
//                    Thread.sleep(2000);
//                    System.out.println("finish business time :==="+  formateDatetimeStringForDate(new Date()));
//                } catch (Exception e1) {
//                    e1.printStackTrace();
//                }
                test2();
                //重试策略在这里不行啊，重试了3次，消息异常了
               // throw  new AmqpRejectAndDontRequeueException("打回");
            }
         // System.out.println("消费成功："+data.getStr());
    }

//    @RabbitListener(queues = AmqpConfig.ROUTINGKEY,containerFactory = "myContainerFactory")    //监听器监听指定的Queue
//    public void normalConsume(MultiData data) {
//        System.out.println("消费成功："+data.getStr());
//    }

    public void test2(){
        System.out.println("<<<<<<<<<<<<<<<<<<<<<insert exception");
        throw new RuntimeException("第1条数据消费异");
    }
}
